package com.zhi.common.validate.common;

import cn.easyes.common.utils.ArrayUtils;
import com.zhi.common.utils.StringUtils;
import com.zhi.common.validate.executor.BizValidatorExecutor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ApplicationContextEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.transaction.support.TransactionTemplate;
import java.lang.reflect.Method;



/**
 * @author ftz-lover
 * @version 1.0
 * @date 2023/9/10 12:10
 */
public class CommonThriftAspect implements BeanDefinitionRegistryPostProcessor, ApplicationListener<ApplicationContextEvent> {

    private static  final Logger LOGGER = LoggerFactory.getLogger(CommonThriftAspect.class);
    private static final String JAVA_PATH_SEPARATOR = ".";

    private BeanDefinitionRegistry beanDefinitionRegistry;

    private String inspectPath = "com.zhi";

    public Object doThriftPointCut(ProceedingJoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Class<?> clazz = joinPoint.getTarget().getClass();
        Method method = methodSignature.getMethod();
        int index = methodSignature.getDeclaringTypeName().lastIndexOf(JAVA_PATH_SEPARATOR);
        String methodName = methodSignature.getDeclaringTypeName().substring(index+1)
            +JAVA_PATH_SEPARATOR+methodSignature.getName();
        Class<?> returnType = methodSignature.getReturnType();

        try {
            if(ArrayUtils.isEmpty(args)){
                return joinPoint.proceed();
            }
            validate(clazz,method,args);
            return joinPoint.proceed();
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }


    }


    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        this.beanDefinitionRegistry  = beanDefinitionRegistry;

    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }

    @Override
    public void onApplicationEvent(ApplicationContextEvent event) {
        if(event instanceof ContextRefreshedEvent){
            try {
                BizValidatorExecutor.init(event.getApplicationContext(),beanDefinitionRegistry,getCustomInspectPackagePath());
            }catch (Exception e){
                throw  new RuntimeException();
            }
        }

    }

    private void validate(Class<?> clazz,Method method,Object[] args) throws Throwable {
        //动态校验
        if(useBizValidator()){
            BizValidatorExecutor.validate(clazz,method,args);
        }
    }

    protected TransactionTemplate getTransactionTemplate(){
        return null;
    }

    protected boolean useBizValidator(){
        return false;
    }

    /**
     * 自定义校验器类扫描包路径
     */
    protected String getCustomInspectPackagePath(){
        return inspectPath;
    }

    public void setInspectPath(String inspectPath){
        if(StringUtils.isNotBlank(inspectPath)){
            this.inspectPath = inspectPath;
        }

    }
}
